package com.maserb.monitor.service.schoolNotice.impl;

import com.maserb.monitor.common.CreateTimeUtils;
import com.maserb.monitor.common.JpushClientUtil;
import com.maserb.monitor.entity.JwOrgEntity;
import com.maserb.monitor.entity.UserEntity;
import com.maserb.monitor.entity.schoolConduct.SchoolConductItemEntity;
import com.maserb.monitor.entity.schoolConduct.StudentConductRecordEntity;
import com.maserb.monitor.entity.schoolNotice.SchoolNoticeEntity;
import com.maserb.monitor.entity.schoolNotice.SchoolNoticeHistoryEntity;
import com.maserb.monitor.entity.schoolStudent.SchoolStudentEntity;
import com.maserb.monitor.entity.schoolStudent.SchoolStudentParentEntity;
import com.maserb.monitor.repository.UserRepository;
import com.maserb.monitor.repository.schoolNotice.SchoolNoticeRepository;
import com.maserb.monitor.repository.schoolOrg.SchoolUserOrgRepository;
import com.maserb.monitor.repository.schoolStudent.SchoolStudentParentRepository;
import com.maserb.monitor.service.author_manage.UserService;
import com.maserb.monitor.service.base.IToolService;
import com.maserb.monitor.service.base.impl.JpaSpecificationServiceImpl;
import com.maserb.monitor.service.jwEducation.JwOrgService;
import com.maserb.monitor.service.schoolNotice.SchoolNoticeHistoryService;
import com.maserb.monitor.service.schoolNotice.SchoolNoticeService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.stereotype.Service;
import org.thymeleaf.util.StringUtils;

import javax.persistence.criteria.*;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

@Service
public class SchoolNoticeServiceImpl extends JpaSpecificationServiceImpl<SchoolNoticeRepository,
        SchoolNoticeRepository, SchoolNoticeEntity, String>
        implements SchoolNoticeService {

    @Autowired
    UserService userService;

    @Autowired
    JwOrgService orgService;

    @Autowired
    SchoolUserOrgRepository userOrgRepository;

    @Autowired
    IToolService toolService;

    @Autowired
    SchoolNoticeHistoryService noticeHistoryService;

    @Autowired
    UserRepository userRepository;

    @Autowired
    SchoolStudentParentRepository parentRepository;




    private Specification<SchoolNoticeEntity> getSpecification(JwOrgEntity orgEntity,String type, String keyword) {
        return new Specification<SchoolNoticeEntity>()  {
            @Override
            public Predicate toPredicate(Root<SchoolNoticeEntity> root, CriteriaQuery<?> criteriaQuery, CriteriaBuilder criteriaBuilder) {
                Path<String> pathTitle = root.get("title");
                Path<String> pathType = root.get("type");
                Path<JwOrgEntity> pathOrg = root.get("org");

                ArrayList<Predicate> list = new ArrayList<Predicate>();
                if (!StringUtils.isEmptyOrWhitespace(keyword)) {
                    list.add(criteriaBuilder.and(criteriaBuilder.like(pathTitle, "%" + keyword + "%")));
                }

                if(!StringUtils.isEmptyOrWhitespace(type)) {
                    list.add(criteriaBuilder.and(criteriaBuilder.equal(pathType, type)));
                }
                if(null!=orgEntity && !StringUtils.isEmptyOrWhitespace(orgEntity.getId())){
                    list.add(criteriaBuilder.and(criteriaBuilder.equal(pathOrg,orgEntity)));
                }

                return criteriaBuilder.and(list.toArray(new Predicate[list.size()]));
            }
        };
    }

    private Specification<SchoolNoticeEntity> getSpecificationBySubject(JwOrgEntity orgEntity,String type, String keyword, String subjectId) {
        return new Specification<SchoolNoticeEntity>()  {
            @Override
            public Predicate toPredicate(Root<SchoolNoticeEntity> root, CriteriaQuery<?> criteriaQuery, CriteriaBuilder criteriaBuilder) {
                Path<String> pathTitle = root.get("title");
                Path<String> pathType = root.get("type");
                Path<JwOrgEntity> pathOrg = root.get("org");
                Path<String> pathSubjectId = root.get("subjectId");

                ArrayList<Predicate> list = new ArrayList<Predicate>();
                if (!StringUtils.isEmptyOrWhitespace(keyword)) {
                    list.add(criteriaBuilder.and(criteriaBuilder.like(pathTitle, "%" + keyword + "%")));
                }

                if(!StringUtils.isEmptyOrWhitespace(type)) {
                    list.add(criteriaBuilder.and(criteriaBuilder.equal(pathType, type)));
                }
                if(!StringUtils.isEmptyOrWhitespace(subjectId)) {
                    list.add(criteriaBuilder.and(criteriaBuilder.equal(pathSubjectId, subjectId)));
                }
                if(null!=orgEntity && !StringUtils.isEmptyOrWhitespace(orgEntity.getId())){
                    list.add(criteriaBuilder.and(criteriaBuilder.equal(pathOrg,orgEntity)));
                }

                return criteriaBuilder.and(list.toArray(new Predicate[list.size()]));
            }
        };
    }

    @Override
    public Page<SchoolNoticeEntity> findAll(Pageable pageable,String orgId, String type, String keyword) {
        JwOrgEntity orgEntity = new JwOrgEntity();
        if(!StringUtils.isEmptyOrWhitespace(orgId)){
            orgEntity = orgService.findOne(orgId);
        }

        return this.findAll(getSpecification(orgEntity,type, keyword), pageable);
    }

    @Override
    public Page<SchoolNoticeEntity> findAll(Pageable pageable, String orgId, String type, String keyword, String subjectId) {
        JwOrgEntity orgEntity = new JwOrgEntity();
        if(!StringUtils.isEmptyOrWhitespace(orgId)){
            orgEntity = orgService.findOne(orgId);
        }
        return this.findAll(getSpecificationBySubject(orgEntity,type, keyword, subjectId), pageable);
    }

    @Override
    public List<SchoolNoticeEntity> findAllBySubjectId(String orgId, String type, String keyword, String subjectId) {
        JwOrgEntity orgEntity = new JwOrgEntity();
        if(!StringUtils.isEmptyOrWhitespace(orgId)){
            orgEntity = orgService.findOne(orgId);
        }
        return this.findAll(getSpecificationBySubject(orgEntity,type, keyword, subjectId),new PageRequest(0,10)).getContent();
    }

    @Override
    public Page<SchoolNoticeEntity> findAll(Pageable pageable, String userId, String clazzId, String type, String keyword,String startTime, String endTime) {
        UserEntity user = new UserEntity();
        List<JwOrgEntity> orgList = new ArrayList<JwOrgEntity>();
        List<String>orgIdList = new ArrayList<String>();
        if(!StringUtils.isEmptyOrWhitespace(userId)){
            user = userService.findOne(userId);
            if(null!=user &&!"".equals( user.getId())){
                orgList = orgService.findByUser(user);
                if(orgList.size()>0){
                    for(JwOrgEntity org:orgList){
                        orgIdList.add(org.getId());
                    }
                }
                orgIdList.add(user.getOrgId());
            }
        }
        return this.findAll(getSpecificationByUserId(orgIdList,clazzId, type, keyword,startTime,endTime),pageable);
    }

    @Override
    public void addNoticeHistory(SchoolNoticeEntity entity) {
        if(!StringUtils.isEmptyOrWhitespace(entity.getType())&& null!=entity.getOrg()){
            List<SchoolNoticeHistoryEntity>historyEntityList = new ArrayList<SchoolNoticeHistoryEntity>();
            String notification_title = "爱兔教育";
            String msg_title =entity.getTitle();
            String msg_content = entity.getContent();
            //学校通知
            if("1".equals(entity.getType())){
                //教师
                List<UserEntity>userEntityList = userRepository.findByOrgId(entity.getOrg().getId());
                for(UserEntity userEntity:userEntityList){
                    if(userEntity!=null){
                        SchoolNoticeHistoryEntity historyEntity = new SchoolNoticeHistoryEntity();
                        historyEntity.setUserId(userEntity.getId());
                        historyEntity.setNoticeId(entity.getId());
                        historyEntity.setIsRead("0");
                        historyEntity.setCreateTime(new Date());
                        historyEntity.setFmtCreateTime(CreateTimeUtils.getCreateTime());
                        historyEntity.setType("1");
                        historyEntity.setOrgId(entity.getOrg().getId());
                        historyEntityList.add(historyEntity);
                        if(!StringUtils.isEmptyOrWhitespace(userEntity.getRegistrationId())){
                            JpushClientUtil.sendToRegistrationId(userEntity.getRegistrationId(),notification_title,msg_title,msg_content,entity.getType(),entity.getId());
                        }

                    }
                }
                //家长
                List<SchoolStudentParentEntity> parentEntityList = parentRepository.findBySchoolId(entity.getOrg().getId());
                for(SchoolStudentParentEntity parentEntity:parentEntityList){
                    if(null!=parentEntity) {
                        SchoolNoticeHistoryEntity historyEntity = new SchoolNoticeHistoryEntity();
                        historyEntity.setUserId(parentEntity.getId());
                        historyEntity.setNoticeId(entity.getId());
                        historyEntity.setIsRead("0");
                        historyEntity.setCreateTime(new Date());
                        historyEntity.setFmtCreateTime(CreateTimeUtils.getCreateTime());
                        historyEntity.setType("1");
                        historyEntity.setOrgId(entity.getOrg().getId());
                        historyEntityList.add(historyEntity);
                        if(!StringUtils.isEmptyOrWhitespace(parentEntity.getRegistrationId())){
                            JpushClientUtil.sendToRegistrationId(parentEntity.getRegistrationId(),notification_title,msg_title,msg_content,entity.getType(),entity.getId());
                        }
                    }
                }
            }
            //班级通知，学习通知
            if("2".equals(entity.getType())||"3".equals(entity.getType())){
                //老师
                List<UserEntity>userEntityList = userOrgRepository.findByOrg(entity.getOrg().getId());
                for(UserEntity userEntity:userEntityList){
                    SchoolNoticeHistoryEntity historyEntity = new SchoolNoticeHistoryEntity();
                    historyEntity.setUserId(userEntity.getId());
                    historyEntity.setNoticeId(entity.getId());
                    historyEntity.setIsRead("0");
                    historyEntity.setCreateTime(new Date());
                    historyEntity.setFmtCreateTime(CreateTimeUtils.getCreateTime());
                    historyEntity.setType(entity.getType());
                    historyEntity.setOrgId(entity.getOrg().getId());
                    historyEntityList.add(historyEntity);
                }
                //家长
                List<SchoolStudentParentEntity> parentEntityList = parentRepository.findByClazzId(entity.getOrg().getId());
                for(SchoolStudentParentEntity parentEntity:parentEntityList){
                    if(null!=parentEntity){
                        SchoolNoticeHistoryEntity historyEntity = new SchoolNoticeHistoryEntity();
                        historyEntity.setUserId(parentEntity.getId());
                        historyEntity.setNoticeId(entity.getId());
                        historyEntity.setIsRead("0");
                        historyEntity.setCreateTime(new Date());
                        historyEntity.setFmtCreateTime(CreateTimeUtils.getCreateTime());
                        historyEntity.setType(entity.getType());
                        historyEntity.setOrgId(entity.getOrg().getId());
                        historyEntityList.add(historyEntity);
                    }
                }
            }
            //作业通知
            if("4".equals(entity.getType())){
                List<SchoolStudentParentEntity> parentEntityList = parentRepository.findByClazzId(entity.getOrg().getId());
                for(SchoolStudentParentEntity parentEntity:parentEntityList){
                    if(null!=parentEntity){
                        SchoolNoticeHistoryEntity historyEntity = new SchoolNoticeHistoryEntity();
                        historyEntity.setUserId(parentEntity.getId());
                        historyEntity.setNoticeId(entity.getId());
                        historyEntity.setIsRead("0");
                        historyEntity.setCreateTime(new Date());
                        historyEntity.setFmtCreateTime(CreateTimeUtils.getCreateTime());
                        historyEntity.setType("4");
                        historyEntity.setOrgId(entity.getOrg().getId());
                        historyEntity.setSubjectId(entity.getSubjectId());
                        historyEntityList.add(historyEntity);
                    }
                }
            }
            noticeHistoryService.save(historyEntityList);
        }
    }

    private Specification<SchoolNoticeEntity> getSpecificationByUserId(List<String> orgIdList, String clazzId, String type, String keyword,String startTime, String endTime){
        return new Specification<SchoolNoticeEntity>() {
            @Override
            public Predicate toPredicate(Root<SchoolNoticeEntity> root, CriteriaQuery<?> criteriaQuery, CriteriaBuilder criteriaBuilder) {
                ArrayList<Predicate> list = new ArrayList<Predicate>();
                Join<SchoolNoticeEntity,JwOrgEntity>joinOrg = root.join("org",JoinType.LEFT);
                Path<String> pathJoinOrg = joinOrg.get("id");
                list.add(criteriaBuilder.and(criteriaBuilder.equal(pathJoinOrg, root.get("org"))));
                Path<Date> pathCreateTime = root.get("createTime");
                Path<String>pathType = root.get("type");
                Path<String> pathTitle = root.get("title");
                if (null!=orgIdList && orgIdList.size()>0) {
                    Expression<String> exp = pathJoinOrg;
                    list.add(exp.in(orgIdList));
                }
                if (!StringUtils.isEmptyOrWhitespace(clazzId)) {
                    list.add(criteriaBuilder.and(criteriaBuilder.equal(pathJoinOrg, clazzId)));
                }
                if (!StringUtils.isEmptyOrWhitespace(type)) {
                    list.add(criteriaBuilder.and(criteriaBuilder.equal(pathType, type)));
                }
                if (!StringUtils.isEmptyOrWhitespace(keyword)) {
                    list.add(criteriaBuilder.and(criteriaBuilder.like(pathTitle, "%" + keyword + "%")));
                }
                if(!StringUtils.isEmptyOrWhitespace(startTime)) {
                    list.add(criteriaBuilder.and(criteriaBuilder.greaterThanOrEqualTo(pathCreateTime, toolService.parseDateFromNormalDateFormat(startTime))));
                }
                if(!StringUtils.isEmptyOrWhitespace(endTime)) {
                    list.add(criteriaBuilder.and(criteriaBuilder.lessThanOrEqualTo(pathCreateTime, toolService.parseDateFromNormalDateFormat(endTime))));
                }
                return criteriaBuilder.and(list.toArray(new Predicate[list.size()]));
            }
        };
    }
}